package com.example.demo.controller;

import com.example.demo.mapper.postgres.StudentMapper;
import com.example.demo.mapper.postgres.TemplateTableMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/home")
public class HomeController {

    @Resource
    private TemplateTableMapper templateTableMapper;

    @Resource
    private StudentMapper studentMapper;

    /**
     * 加上事务后，问题解决，不是最优解，由于sqlsession 的生命周期由spring boot 管理，请求结束后会话
     *
     * @return
     */
    @GetMapping("/test1")
    @Transactional(rollbackFor = Exception.class)
    public String test1() {

        List<String> tempIds = new ArrayList<>(List.of("1", "2", "3", "4"));
        String tempTableName = "pg_temp.temp_table_" + randomString(10);
        templateTableMapper.createTempTable(tempTableName);
        templateTableMapper.insertTempIds(tempTableName, tempIds);

        var records = studentMapper.list(tempTableName);

        return "ok";
    }

    /**
     * 这个方式在并发的情况下会出现临时表不存在的问题
     *
     * @return
     */
    @GetMapping("/test2")
    public String test2() {

        List<String> tempIds = new ArrayList<>(List.of("1", "2", "3", "4"));
        String tempTableName = "pg_temp.temp_table_" + randomString(10);
        templateTableMapper.createTempTable(tempTableName);
        templateTableMapper.insertTempIds(tempTableName, tempIds);

        var records = studentMapper.list(tempTableName);

        return "ok";
    }

    @Resource
    private SqlSessionFactory sqlSessionFactory;

    /**
     * 最优的写法，请求结束，临时表删除
     *
     * @return
     */
    @GetMapping("/test3")
    public String test3() {
        SqlSession session = sqlSessionFactory.openSession();

        var tempTableMapper = session.getMapper(TemplateTableMapper.class);

        String tempTableName = "pg_temp.temp_table_" + randomString(10);
        tempTableMapper.createTempTable(tempTableName);

        List<String> tempIds = new ArrayList<>(List.of("1", "2", "3", "4"));
        tempTableMapper.insertTempIds(tempTableName, tempIds);

        var studMapper = session.getMapper(StudentMapper.class);
        studMapper.list(tempTableName);

        session.close();

        return "OK";
    }

    private static final SecureRandom RANDOM = new SecureRandom();
    private static final String CHARS = "abcdefghijklmnopqrstuvwxyz";

    public static String randomString(int length) {
        StringBuilder ret = new StringBuilder();
        for (int i = 0; i < length; i++) {
            ret.append(CHARS.charAt(RANDOM.nextInt(CHARS.length())));
        }
        return ret.toString();
    }
}